//
// Created by dave on 18-7-29.
//

#pragma once
#include <string>
#include <algorithm>
#include "encodable.h"
#include "msg_body.h"
#include "data_utils.h"

class data_pack : public encodable {
public:
    std::vector<unsigned char> encode() override {
        std::vector<unsigned char> bb = body->encode();
        std::vector<unsigned char> ret;
        ret.reserve(bb.size() + 20);
        write_word(ret, msg_id);
        write_word(ret, bb.size()); // 消息包封装项，这里假定不分包，数据不加密
        write_bcd(ret, sim);
        write_word(ret, seq_no);
        for_each(bb.cbegin(), bb.cend(), [&ret](unsigned char val) {
            ret.push_back(val);
        });
        ret.push_back(::checksum(ret));

        // 转义
        std::vector<unsigned char> escaped;
        escaped.reserve(ret.size() + 50);
        escaped.push_back(0x7E);
        for_each(ret.cbegin(), ret.cend(), [&escaped](unsigned char val) {
            if (val == 0x7D) {
                escaped.push_back(0x7D);
                escaped.push_back(0x01);
            } else if (val == 0x7E) {
                escaped.push_back(0x7D);
                escaped.push_back(0x02);
            } else {
                escaped.push_back(val);
            }
        });
        escaped.push_back(0x7E); //标识位(0x7E)
        return escaped;
    }

    unsigned short get_msg_id() { return msg_id; }
    void set_msg_id(unsigned short msg_id) { this->msg_id = msg_id; }
    std::string get_sim() { return sim; }
    void set_sim(std::string sim) { this->sim = sim; }
    unsigned short get_seq_no() { return seq_no; }
    void set_seq_no(unsigned short seq_no) { this->seq_no = seq_no; }
    bool is_encrypted() { return encrypted; }
    void set_encrypted(bool encrypted) { this->encrypted = encrypted; }
    bool is_split() { return split; }
    void set_split(bool split) { this->split = split; }
    unsigned short get_content_size() { return content_size; }
    void set_content_size(unsigned short content_size) { this->content_size = content_size; }
    unsigned short get_pkg_count() { return pkg_count; }
    void set_pkg_count(unsigned short pkg_count) { this->pkg_count = pkg_count; }
    unsigned short get_pkg_no() { return pkg_no; }
    void set_pkg_no(unsigned short pkg_no) { this->pkg_no = pkg_no; }
    unsigned char get_checksum() { return checksum; }
    void set_checksum(unsigned char checksum) { this->checksum = checksum; }
    std::shared_ptr<msg_body> get_body() { return body; }
    void set_body(std::shared_ptr<msg_body> body) { this->body = body; }

private:
    /// 消息ID
    unsigned short msg_id;
    /// 手机号
    std::string sim;
    /// 流水号
    unsigned short seq_no;
    /// 是否加密
    bool encrypted;
    /// 是否分包
    bool split;
    /// 消息体长度
    unsigned short content_size;
    /// 分包后的包数，未分包时为0
    unsigned short pkg_count = 0;
    /// 包序号，示分包时为0
    unsigned short pkg_no = 0;
    /// 校验码
    unsigned char checksum;
    /// 消息体
    std::shared_ptr<msg_body> body;
};

